package com.example.ormsqlsplicingframe1.orm.wrapper;

import com.baomidou.mybatisplus.annotation.FieldFill;
import com.baomidou.mybatisplus.annotation.TableField;
import com.example.ormsqlsplicingframe1.orm.Util.StringUtil;
import com.example.ormsqlsplicingframe1.orm.jdbc.SelectWrapperJdbc;
import com.example.ormsqlsplicingframe1.orm.note.AddBatch;
import com.example.ormsqlsplicingframe1.orm.note.Title;
import com.example.ormsqlsplicingframe1.orm.note.TableFieldKey;
import com.example.ormsqlsplicingframe1.utlis.NodeSqlUtil;
import lombok.SneakyThrows;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class InsertWrapper {

    private Object obj;

    private Object columnKey = null;


   private SimpleDateFormat  dateFormat = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");


    public InsertWrapper(Object obj) {
        this.obj = obj;
        getAllClass(obj);
    }

    private com.example.ormsqlsplicingframe1.orm.wrapper.Title title = new com.example.ormsqlsplicingframe1.orm.wrapper.Title();

    private Column column = new Column();

    public com.example.ormsqlsplicingframe1.orm.wrapper.Title title(){
        return title;
    }

    public Column column(){
        return column;
    }

    public InsertWrapper title(String title){
        title().title(title);
        return this;
    }

    public InsertWrapper column(String columnName,Object value ){
        column().insertAdd(columnName,value);
        return this;
    }

    public InsertWrapper column(String columnName,Object value,Class type){
        column().insertAdd(columnName,value);
        return this;
    }

    public String getSql(){

        StringBuilder sb = new StringBuilder();

        if (title().getSql() != null){
            sb.append("INSERT INTO "+title().getSql());
        }

        if (column().getSql() != null){
            sb.append(column().getSql());
        }
        return sb.toString();
    }

    private List<Object> listType = new ArrayList<>();

    public Object insert(){
        log();
       if (SelectWrapperJdbc.insert(getSql(),values()) == 0) throw new IllegalStateException("添加失败");
        return columnKey;
    }

    @SneakyThrows
    private void getAllClass(Object value) {
        Class<?> aClass = value.getClass();
        wrapper(aClass);
        Class<?> superclass = aClass.getSuperclass();
        if ( superclass != null && superclass != Object.class){
            getAllClass(superclass.newInstance());
        }
    }

    private void wrapper(Class<?> aClass){


        Title annotation = aClass.getAnnotation(Title.class);
        if (annotation != null){
            title(annotation.titleName());
        }
        Field[] declaredFields = aClass.getDeclaredFields();
        for (Field field : declaredFields) {

            TableField tableField = field.getAnnotation(TableField.class);

            TableFieldKey idKey = field.getAnnotation(TableFieldKey.class);
            try {
                Object value = null;
                if (tableField != null && tableField.exist()){
                    field.setAccessible(true);
                    //会拿到一个唯一值
                    if (idKey != null){
                         value = atPresentKeyType(field);
                        columnKey = value;
                    }else {
                        value = field.get(obj);
                    }

                    if (tableField.fill() == FieldFill.INSERT){
                        value = isThisDateType(field);
                    }

                    String name = StringUtil.javaTurnSql(field.getName());

                    if (value != null) column(name,value);
                }
            }catch (Exception e){
                e.printStackTrace();
                throw new IllegalStateException("获取字段值失败:"+field.getName());
            }
        }

    }

    //判断当前的key是什么类型 自动返回一个时间搓
    private Object atPresentKeyType(Field field){
        Date date = new Date();
        if (field.getType() == Integer.class){
            Long time = date.getTime();
            Integer value = time.intValue();
            return value;
        }
        if (field.getType() == Long.class){
            return date.getTime();
        }

        if (field.getType() == String.class){
            return dateFormat.format(date);
        }
        throw new RuntimeException("当前没有支持的类型是:"+field.getType());
    }

    //判断时间字段是什么类型
    private Object isThisDateType(Field field){
        Date date = new Date();
        if (field.getType() == Date.class){
            return date ;
        }

        if (field.getType() == String.class){
            return dateFormat.format(date);
        }

        if (field.getType() == Long.class){
            return date.getTime();
        }

        throw  new RuntimeException("当前时间类型不支持:"+field.getType());

    }

    public List<Object> values(){
        return column().getValues();
    }

    public InsertWrapper() {
    }

    private static InsertWrapper insertWrapper = null;

    public static InsertWrapper newInsertWrapper(Object object) {

        if (insertWrapper == null){
            if (insertWrapper == null){
                synchronized (InsertWrapper.class){
                    if (insertWrapper == null){
                        insertWrapper = new InsertWrapper(object);
                    }
                }
            }
        }
        return insertWrapper;
    }

    public static InsertWrapper newInsertWrapper() {

        if (insertWrapper == null){
            if (insertWrapper == null){
                synchronized (InsertWrapper.class){
                    if (insertWrapper == null){
                        insertWrapper = new InsertWrapper();
                    }
                }
            }
        }
        return insertWrapper;
    }

    private static final Logger logger = LoggerFactory.getLogger(InsertWrapper.class);

    private void log(){
        logger.info("这是sql日志"+getSql());

        List<Object> values = values();
        ArrayList<Object> objects = new ArrayList<>(values.size());
        values.forEach(row ->{
            objects.add(disposeDate(row)+"("+row.getClass().getSimpleName()+")");
        });
        logger.info(objects.toString());

    }

    //处理时间
    private Object disposeDate(Object obj){

        if (obj.getClass()==Date.class){
            return dateFormat.format(obj);
        }
        return obj;
    }

}
